﻿using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;
using mfNordic;
using mfNordic.Radios;

namespace mfNordicExample
{
    public class Program
    {
        private static readonly AutoResetEvent TransmitSignal = new AutoResetEvent(false);
		private static readonly AutoResetEvent ReceiveSignal = new AutoResetEvent(false);
		private static Nrf24L01P _radio;
		
		private static DataReceivedEventArgs _dataReceivedEventArgs;
		
        public static void Main()
        {
            _radio = new Nrf24L01P(SPI_Devices.SPI1, Pins.GPIO_PIN_D0, Pins.GPIO_PIN_D1, Pins.GPIO_PIN_D2);

            _radio.OnDataReceived += RadioOnDataReceived;
            _radio.OnTransmitFailed += RadioOnTransmitFailed;
            _radio.OnTransmitSuccess += RadioOnTransmitSucess;
            _radio.OnDataReceiveFailure += RadioDataReceivedFailure;

			_radio.DynamicPayloadEnabled = true;
            _radio.DynamicAckEnabled = true;
			_radio.Enable = true;
			_radio.PowerUp = true;
			_radio.Mode = Mode.Transmitter;
			
			Thread.Sleep(10);
			
			Debug.Print("Sending a packet using default configuration no acknowledge");
			RadioSend(false);
			
			Debug.Print("Sending a packet using default configuration with acknowledge");
			
			RadioSend(true);
			
			_radio.Mode = Mode.Receiver;
			_radio.PowerUp = true;
			
			Thread.Sleep(10);
			
			Debug.Print("Waiting to receive data");
			
			do
			{
				ReceiveSignal.WaitOne();
				
				Debug.Print("Received: " + _dataReceivedEventArgs.Payload.Length + " bytes on Pipe: " + _dataReceivedEventArgs.Pipe);
			} while(true);
        }
		
		private static void RadioSend(Boolean ack)
		{
			_radio.WriteTransmitPayload(new Byte[] {0,1,2,3,4,5}, ack);
			
			_radio.Enable = false;
			WaitMicroseconds(10);
			_radio.Enable = true;
			
			Debug.Print("Waiting for transmit");
			TransmitSignal.WaitOne();
		}
		
        private static void RadioDataReceivedFailure(object sender, DataReceiveFailureEventArgs e)
        {
            Debug.Print(String.Concat("RadioDataReceivedFailure From: ", e.Pipe));
        }

        private static void RadioOnTransmitSucess(object sender, EventArgs e)
        {
            Debug.Print("RadioOnTransmitSucess");

            TransmitSignal.Set();
        }

        private static void RadioOnTransmitFailed(object sender, TransmitFailedEventArgs e)
        {
            Debug.Print("RadioOnTransmitFailed");

            TransmitSignal.Set();
        }

        private static void RadioOnDataReceived(object sender, DataReceivedEventArgs e)
        {
            Debug.Print("RadioOnDataReceived");
			
			_dataReceivedEventArgs = e;
			
			ReceiveSignal.Set();
        }

        private static void WaitMicroseconds(Int32 microseconds)
        {
            Int64 ticks = Utility.GetMachineTime().Ticks;
            while ((Utility.GetMachineTime().Ticks - ticks) < (microseconds * TimeSpan.TicksPerMillisecond))
            {
            }
        }
    }
}
